#include <QCoreApplication>
#include <QWebSocketServer>
#include <QWebSocket>
#include <QList>
#include <QDebug>

class WebSocketServer : public QObject {
    Q_OBJECT
public:
    explicit WebSocketServer(QObject *parent = nullptr)
        : QObject(parent), m_pWebSocketServer(new QWebSocketServer("WebSocket Server", QWebSocketServer::NonSecureMode, this)) {
        connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &WebSocketServer::onNewConnection);
        connect(m_pWebSocketServer, &QWebSocketServer::closed, this, &WebSocketServer::onClosed);

        if (m_pWebSocketServer->listen(QHostAddress::Any, 12345)) {
            qDebug() << "Server started!";
        } else {
            qDebug() << "Server could not start!";
        }
    }

    ~WebSocketServer() {
        foreach (QWebSocket *client, m_clients) {
            client->close();
        }
        m_clients.clear();
        m_pWebSocketServer->close();
    }

private slots:
    void onNewConnection() {
        QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
        connect(pSocket, &QWebSocket::textMessageReceived, this, &WebSocketServer::processTextMessage);
        connect(pSocket, &QWebSocket::disconnected, this, &WebSocketServer::socketDisconnected);

        m_clients.append(pSocket);
        qDebug() << "New client connected:" << pSocket->peerAddress().toString();
    }

    void processTextMessage(QString message) {
        QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
        if (pClient) {
            qDebug() << "Message received from client:" << message;
            broadcastMessage("Echo: " + message);
        }
    }

    void socketDisconnected() {
        QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
        if (pClient) {
            qDebug() << "Client disconnected:" << pClient->peerAddress().toString();
            m_clients.removeAll(pClient);
            pClient->deleteLater();
        }
    }

    void onClosed() {
        qDebug() << "Server closed.";
    }

    void broadcastMessage(const QString &message) {
        for (QWebSocket *client : qAsConst(m_clients)) {
            if (client->isValid()) {
                client->sendTextMessage(message);
            }
        }
    }

private:
    QWebSocketServer *m_pWebSocketServer;
    QList<QWebSocket *> m_clients;
};

#include "main.moc"

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    WebSocketServer server;

    return a.exec();
}
